若依框架中权限管理的后端实现 您所在的位置:网站首页 若依 权限字符 若依框架中权限管理的后端实现

若依框架中权限管理的后端实现

2024-02-26 05:02| 来源: 网络整理| 查看: 265

文章目录 RBAC模型介绍权限的分类菜单权限和按钮权限的实现接口权限的实现数据权限的实现

RBAC模型介绍 若依框架的权限管理功能是基于RBAC模型来实现的,即:系统中所有的权限,都是基于角色来控制的框架对权限的控制,不仅支持菜单的功能,还支持菜单中每一个按钮的权限控制

RBAC模型包含的表有下面五张: 1. 用户表 2. 角色表 3. 权限菜单表 4. 用户和角色的关联表 5. 角色和权限菜单的关联表 关系如下:

权限的分类 菜单权限 用户登录之后能看见哪些菜单按钮权限 用户在页面上看见哪些按钮,如新增、删除、修改、导出等按钮接口权限 用户能发送哪些请求给后端接口,与按钮一一对应数据权限 用户有权限访问后端的某个接口后,能看到哪些数据,如权限大的用户能看到更多的数据 菜单权限和按钮权限的实现

具体代码如下: controller层:SysLoginController下的getRouters()方法

/** * 获取路由信息 * * @return 路由信息 */ @GetMapping("getRouters") public AjaxResult getRouters() { Long userId = SecurityUtils.getUserId(); List menus = menuService.selectMenuTreeByUserId(userId); return AjaxResult.success(menuService.buildMenus(menus)); }

service层:SysMenuServiceImpl下的selectMenuTreeByUserId()方法

/** * 根据用户ID查询菜单 * * @param userId 用户名称 * @return 菜单列表 */ @Override public List selectMenuTreeByUserId(Long userId) { List menus = null; if (SecurityUtils.isAdmin(userId)) { menus = menuMapper.selectMenuTreeAll(); } else { menus = menuMapper.selectMenuTreeByUserId(userId); } return getChildPerms(menus, 0); }

先判断用户是否为超级管理员,若是,则返回所有权限菜单,若不是,则根据用户id返回菜单

mapper层:SysMenuMapper

超级管理员执行的sql

/** * 根据用户ID查询菜单 * * @return 菜单列表 */ public List selectMenuTreeAll(); select distinct m.menu_id, m.parent_id, m.menu_name, m.path, m.component, m.`query`, m.visible, m.status, ifnull(m.perms,'') as perms, m.is_frame, m.is_cache, m.menu_type, m.icon, m.order_num, m.create_time from sys_menu m where m.menu_type in ('M', 'C') and m.status = 0 order by m.parent_id, m.order_num

其他用户执行的sql

/** * 根据用户ID查询菜单 * * @param userId 用户ID * @return 菜单列表 */ public List selectMenuTreeByUserId(Long userId); select distinct m.menu_id, m.parent_id, m.menu_name, m.path, m.component, m.`query`, m.visible, m.status, ifnull(m.perms,'') as perms, m.is_frame, m.is_cache, m.menu_type, m.icon, m.order_num, m.create_time from sys_menu m left join sys_role_menu rm on m.menu_id = rm.menu_id left join sys_user_role ur on rm.role_id = ur.role_id left join sys_role ro on ur.role_id = ro.role_id where ur.user_id = #{params.userId} AND m.menu_name like concat('%', #{menuName}, '%') AND m.visible = #{visible} AND m.status = #{status} order by m.parent_id, m.order_num 接口权限的实现

以获取用户列表的接口为例

/** * 获取用户列表 */ @PreAuthorize("@ss.hasPermi('system:user:list')") @GetMapping("/list") public TableDataInfo list(SysUser user) { startPage(); List list = userService.selectUserList(user); return getDataTable(list); }

接口权限是基于SpringSecurity的注解@PreAuthorize实现的 若依框架在PermissionService中重新定义了hasPermi()方法

/** * RuoYi首创 自定义权限实现,ss取自SpringSecurity首字母 * * @author ruoyi */ @Service("ss") public class PermissionService { . . . /** * 验证用户是否具备某权限 * * @param permission 权限字符串 * @return 用户是否具备某权限 */ public boolean hasPermi(String permission) { if (StringUtils.isEmpty(permission)) { return false; } LoginUser loginUser = SecurityUtils.getLoginUser(); if (StringUtils.isNull(loginUser) || CollectionUtils.isEmpty(loginUser.getPermissions())) { return false; } PermissionContextHolder.setContext(permission); return hasPermissions(loginUser.getPermissions(), permission); } . . . }

每次带有注解@PreAuthorize的请求过来,就会先执行hasPermi(),判断是否具备某权限,若返回false则没有权限,若返回true,则有权限,可以执行该接口

数据权限的实现

数据权限的核心就是使用aop切面,拼接sql语句 这里的dataScope参数通过实行切面传入 在service层里添加注解@DataScope,这是若依框架中的一个自定义注解

通过监听这个注解来执行切面,DataScopeAspect为定义切面的类 这里的基本思想就是把要拼接的sql语句传到基类中的params里,params是BaseEntity类中的一个map类型的属性 这里第一步是清空params里面的dataScope,然后再判断其是否具有权限,再把拼接后的sql语句放到params里的dataScope里面

/** * 拼接权限sql前先清空params.dataScope参数防止注入 */ private void clearDataScope(final JoinPoint joinPoint) { Object params = joinPoint.getArgs()[0]; if (StringUtils.isNotNull(params) && params instanceof BaseEntity) { BaseEntity baseEntity = (BaseEntity) params; baseEntity.getParams().put(DATA_SCOPE, ""); } } protected void handleDataScope(final JoinPoint joinPoint, DataScope controllerDataScope) { // 获取当前的用户 LoginUser loginUser = SecurityUtils.getLoginUser(); if (StringUtils.isNotNull(loginUser)) { SysUser currentUser = loginUser.getUser(); // 如果是超级管理员,则不过滤数据 if (StringUtils.isNotNull(currentUser) && !currentUser.isAdmin()) { String permission = StringUtils.defaultIfEmpty(controllerDataScope.permission(), PermissionContextHolder.getContext()); dataScopeFilter(joinPoint, currentUser, controllerDataScope.deptAlias(), controllerDataScope.userAlias(), permission); } } }

数据权限分为五种,分别是全部数据权限、自定数据权限、部门数据权限、部门及以下数据权限、仅本人数据权限,拼接对应的sql语句 最后将拼接好后的sql语句放到params.dataScope里面



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有